#!/usr/bin/python2.5
import subprocess
import re
import os
from numpy import *
import time

NumEntryRe  = re.compile("Aggiunte\s(?P<num_entry>\d+)\sentry")
MaxScoreRe  = re.compile("max\sscore\s+=\s+(?P<max_score>\d+)")
SnapIntRe   = re.compile("snap_interval\s<(?P<snap_interval>\d+)>")
MaxGenRe    = re.compile("max_generations\s<(?P<max_gen>\d+)>") 
BestRe      = re.compile("^best\s*=\s*(?P<BestVal>\d+\.\d*)")
MeanRe      = re.compile("mean\s*=\s*(?P<MeanVal>\d+\.\d*)")
HamRe       = re.compile("ham_best\s*=\s*(?P<HamBest>\d+\.\d*)")
TimeRe      = re.compile("\sTime:\s+(?P<EvoTime>\d+\.\d+)")

def eseguiSingleRun(cmdList,baseIndex = 0, reportFile = ""):
    ParseState = 1
        
    
    #cmd_string = "./ArchLUT5Fwk"
    compileProc = subprocess.Popen(cmdList,bufsize = 1,stderr=subprocess.PIPE,stdout=subprocess.PIPE,stdin=subprocess.PIPE)
    GenNumber = baseIndex
    linea = compileProc.stdout.readline()
    BestVal = 0
    EvoTime = 0
    t0 = time.time()
    while(linea != ""):
        linea = linea.strip(" \n")
        #if ParseState<=2:
        #print "%d: %s" % (ParseState, linea)
        if ParseState == 0: #ricerca numero entry
            match = NumEntryRe.search(linea)
            if match != None:
                NumEntry = float(match.group("num_entry"))
                print "NumEntry: [%.0f]" % NumEntry,
                ParseState = 1
                
        elif ParseState == 1: #Ricerca max score
            match = MaxScoreRe.search(linea)
            if match != None:
                MaxScore = float(match.group("max_score"))
                print "MaxScore: [%0.f]" % MaxScore,
                #ActFac = MaxScore / NumEntry
                ParseState = 2
                
        elif ParseState == 2: #Ricerca snap_interval
            match = SnapIntRe.search(linea)
            if match != None:
                SnapInterval = int(match.group("snap_interval"))
                print "SnapInterval: [%d]" % SnapInterval
                print "Gen\tBest\t\tMean\t\tHamBest\t\tGenTime"
                GenNumber += SnapInterval
                ParseState = 3
    
        elif ParseState == 3:   #Cerca best
            match = BestRe.search(linea)
            if match != None:
                BestVal = 100*float(match.group("BestVal")) / MaxScore
                print "%d\t%f" % (GenNumber,BestVal),
                ParseState = 4
            
                
        elif ParseState == 4:   #Cerca mean
            match = MeanRe.search(linea)
            if match != None:
                MeanVal = 100*float(match.group("MeanVal")) / MaxScore
                print "\t%f" % (MeanVal),
                ParseState = 5
                GenNumber += SnapInterval
            match = TimeRe.search(linea)
            if match != None:
                EvoTime = float(match.group("EvoTime"))
                print "\nTempo di evoluzione: [%f]" % EvoTime
                
        elif ParseState == 5:   #Cerca ham_best
            match = HamRe.search(linea)
            if match != None:
                HamBest = float(match.group("HamBest"))
                print "\t%f\t" % (HamBest),
                t = time.time()
                print t-t0
                t0 = t
                ParseState = 3
                
                
        linea = compileProc.stdout.readline()
    
    print ""
    if BestVal < 100:
        GenNumber = 0
    return GenNumber, EvoTime

def makeTest(cmdList,num_run, reportFile = "", finishCmdList = []):
    
    max_runs  = 10000
    runArray  = []
    timeArray = []
    SuccessRun = 0
    
    for i in range(num_run):
        print "-"*60
        print str(i).center(60)
        print "-"*60
        index = 0
        for cmd in cmdList:
            index, evoTime = eseguiSingleRun(cmd,index)
            for finCmd in finishCmdList:
                p = subprocess.Popen(finCmd, shell=True)
                sts = os.waitpid(p.pid, 0)
        if index > 0:
                SuccessRun += 1		
                runArray.append(index)
                timeArray.append(evoTime)
    
    runArray  = array(runArray)
    timeArray = array(timeArray)
    
    print "#Generazioni:\tMedia: %.3f\tDevStd: %f\tMin: %d\tMax: %d" % (runArray.mean(), sqrt(runArray.var()), runArray.min(), runArray.max())
    print "#evoTime:\tMedia: %.3f\tDevStd: %f\tMin: %f\tMax: %f" % (timeArray.mean(), sqrt(timeArray.var()), timeArray.min(), timeArray.max())
    print "Success: %.2f%%" % (100* SuccessRun / (float(num_run)))

    if reportFile != "":
        rF = open(reportFile,'w')
        rF.write("Gen:\tMedia: %f\tDevStd: %f\tMin: %d\tMax: %d\n" % (runArray.mean(), sqrt(runArray.var()), runArray.min(), runArray.max()))
        rF.write(str(runArray))
        rF.write("\nTime:\tMedia: %f\tDevStd: %f\tMin: %f\tMax: %f\n" % (timeArray.mean(), sqrt(timeArray.var()), timeArray.min(), timeArray.max()))
        rF.write(str(timeArray))
        rF.write("Success: %.2f%%\n" % (100* SuccessRun / (float(num_run))))
        
        rF.close()
    
def main():
    
    cmdList = [["./LUT5Fwk"]]
    makeTest(cmdList,10,"report.txt")
    
    #cmdList = [["./ArchLUT5Fwk", "prova5.cnf"]]
    #makeTest(cmdList,30,"EvoPar5.txt")
    
    #cmdList = [["./ArchLUT5Fwk", "prova6.cnf"]]
    #makeTest(cmdList,30,"EvoPar6.txt")    
    
    #cmdList = [["./ArchLUT5Fwk", "prova7.cnf"]]
    #makeTest(cmdList,30,"EvoPar7.txt")
    
    #cmdList = [["./ArchLUT5Fwk", "prova8.cnf"]]
    #makeTest(cmdList,30,"EvoPar8.txt")
    
    #cmdList = [["./ArchLUT5Fwk", "provaLink5.cnf"], ["./ArchLUT5Fwk", "provaLink56.cnf"], ["./ArchLUT5Fwk", "provaLink67.cnf"], ["./ArchLUT5Fwk", "provaLink78.cnf"]]
    #finishCmdList = ["mv snap/bestpop.dat ./"]
    #makeTest(cmdList,30,"EvoReport/EvoLink567.txt", finishCmdList = finishCmdList)
    
if __name__ == "__main__":
    main()
